/*
 * Jiri Cigler
 * ciglej1@fel.cvut.cz 
 *
 * Copyright (C) 2007 Jirka Cigler <ciglej1@fel.cvut.cz>
 * 
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
 * USA
 */ 

/**
 * \file shopSolver.cc
 * \author Jiri Cigler
 * \brief Definition  of ShopSolver methods
 * \see ShopSolver
 */
//#include "gecode/support/random.icc"
//#include "gecode/support/random.hh"
#include "../src/types.hh"
#include "shopSolver.hh"
#include <algorithm>
#include "../src/shopScheduler.hh"

using namespace std;


ShopSolver::~ShopSolver(){}


ShopSolver::ShopSolver(int iJobs, int iTasksInJob, int iMachines, unsigned int iMaxTime, vector<Task> & ac)
	: q(this,iTasksInJob*iJobs+1,0,iMaxTime)
	  {
		jobs = iJobs;
		tasksInJob = iTasksInJob;
		machines = iMachines;	
		solve(ac);		
	}

void ShopSolver::solve(vector<Task> &ac){

	std::vector<Task>::iterator it1;
	std::vector<Task>::iterator it;
	std::vector<unsigned int>::iterator it_pre;
	int maxMachineID = 0;
	/*Post constraints based on prereqirements*/
	for(it = ac.begin(); it!=ac.end();it++){
		for( it_pre = it->prerequirements.begin(); it_pre != it->prerequirements.end(); it_pre++){
			post(this, ((q[*it_pre] + ac.at(*it_pre).processingTime) <= q[it->id]));
		}
		if (it->processor > maxMachineID)
			maxMachineID = it->processor;

	}

	/*Post constraints based on exclusion of tasks on processors*/
	
	for(int i=0; i <= maxMachineID; i++){ 
		for(it = ac.begin(); it!=ac.end(); it++){
			if(it->processor == i){
				for(it1 = it+1; it1!=ac.end(); it1++){
					if((it1->processor == i )&& (it1!=it) ){
						post(this,tt((~(q[it->id]+it->processingTime <= q[it1->id])||~(q[it1->id]+it1->processingTime <= q[it->id]))));
					}
				}
			}
		}
	};

//	post(this, best == q[jobs*tasksInJob]);
	branch(this,q, INT_VAR_REGRET_MIN_MAX , INT_VAL_MIN);
//	branch(this,q, BVAR_MIN_MIN,BVAL_SPLIT_MIN);
	//branch(this, q, BVAR_DEGREE_MIN, BVAL_MIN);
};

void ShopSolver::result(unsigned int **& r,vector<SortTableElement> &sortTable ,bool verbose){
	for(std::vector<SortTableElement>::iterator it = sortTable.begin(); it!=sortTable.end()-1; it++){
		if(verbose){
			std::cout << "[prev, actual] = [ ";
			std::cout << it->previous << ", ";
			std::cout << it->actual << " ]" << std::endl;
		}
		r[(it->previous - it->previous%tasksInJob)/tasksInJob][it->previous%tasksInJob] = (unsigned int )q[it->actual].val();
	};
};


void ShopSolver::print(){
	for (int i = 0; i < q.size(); i++) {

		std::cout << i << ": ";
		std::cout <<  "" << "[s, pt, m] = [";
		//	std::cout << q[i] << "," << q[i] << ", ";
		std::cout << q[i].val() << "] ";

		std::cout << std::endl;
	};
	std::cout << "------------"<< std::endl;

};

void ShopSolver::constrain(ShopSolver * iShopSolver){
//	rel(this, best, IRT_LE, static_cast<ShopSolver*>(iShopSolver)->best.val());
};


